﻿#region Copyright
/// <copyright>
/// Copyright (c) 2008 Ilia Shramko.
/// Released under the terms of the GNU General Public License.
/// </copyright>
#endregion

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text;

namespace Osh.Dvb
{
	public class DescriptorReader : BinaryReader
	{
		public DescriptorReader(Stream stream)
			: base(stream)
		{
		}

		public DescriptorReader(Stream stream, Encoding encoding)
			: base(stream, encoding)
		{
		}

		public IDescriptor[] ReadDescriptors(int descriptorsLoopLength, bool ignoreUnknownDescriptors)
		{
			if(descriptorsLoopLength <= 0)
				return new IDescriptor[0];

			List<IDescriptor> descriptors = new List<IDescriptor>();
			do
			{
				int read;
				IDescriptor descriptor = ReadDescriptor(ignoreUnknownDescriptors, out read);
				descriptorsLoopLength -= read;
				if(descriptor != null)
					descriptors.Add(descriptor);
			}
			while(descriptorsLoopLength > 0);

			return descriptors.ToArray();
		}

		public IDescriptor ReadDescriptor()
		{
			int read;
			return ReadDescriptor(false, out read);
		}

		private IDescriptor ReadDescriptor(bool ignoreUnknownDescriptors, out int read)
		{
			byte tag = this.ReadByte();
			int length = (int)this.ReadByte();

			IDescriptor descriptor = null;
			switch((DescriptorTags)tag)
			{
				case DescriptorTags.ShortEventDescriptor:
					descriptor = new ShortEventDescriptor(this, length);
					break;

				case DescriptorTags.ExtendedEventDescriptor:
					descriptor = new ExtendedEventDescriptor(this, length);
					break;

				//case 0x50: // component_descriptor
				//    break;
				//case 0x54: // content_descriptor
				//    break;
				//case 0x55: // parental_rating_descriptor
				//    break;

				case DescriptorTags.TeletextDescriptor:
					descriptor = new TeletextDescriptor(this, length);
					break;

				default:
					if(ignoreUnknownDescriptors)
						this.SkipBytes(length);
					else
						descriptor = new GenericDescriptor(tag, this.ReadBytes(length));
					break;
			}
			read = 2 + length;

			return descriptor;
		}

		public NameValueCollection ReadEventItems(int itemsLoopLength, LanguageCode languageCode)
		{
			NameValueCollection result = new NameValueCollection();

			while(itemsLoopLength > 0)
			{
				int keyLength = this.ReadByte();
				string key = TextEncoding.Default.GetString(this.ReadBytes(keyLength), languageCode);

				int valueLength = this.ReadByte();
				string value = TextEncoding.Default.GetString(this.ReadBytes(valueLength), languageCode);

				result.Add(key, value);

				itemsLoopLength -= (keyLength + valueLength + 2);
			}

			return result;
		}

	}
}
